package com.example.nacos.ribbon.controller;

import com.example.nacos.ribbon.model.Product;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @ClassName : MyRibbonController
 * @Description : 默认rabbon实现客户端负载均衡
 * @Author : tianshuo
 * @Date: 2021-04-03 22:31
 */
@RestController
public class MyRibbonController {

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private DiscoveryClient discoveryClient;

    private static final Logger logger = LoggerFactory.getLogger(MyRibbonController.class);

    @GetMapping("/my/loadBalance/{id}")
    public Product product(@PathVariable("id") Integer id) {

        String uri = getUri("nacos-provider");
        return restTemplate.getForObject(uri + "/product/" + id, Product.class);
    }

    AtomicInteger atomicInteger = new AtomicInteger();

    /**
     * 获取uri路径
     *
     * @param serviceName
     * @return
     */
    private String getUri(String serviceName) {
        List<ServiceInstance> instances = discoveryClient.getInstances(serviceName);

        int index = loadBalance2(instances.size());
        logger.info("负载均衡索引为：{}", index);

        return instances.get(index).getUri().toString();
    }

    //HTTP请求	40000	119	15	37	95	341	0	38595	0.0279	895.997132809175	357.83517992742424	117.60192054885424
    private synchronized int loadBalance(int count) {

        return atomicInteger.getAndIncrement() % count;

       /* for(;;) {
            int current = atomicInteger.get();
            int next = current +1;
            if(atomicInteger.compareAndSet(current,next)) {
                int index = current % instances.size();
                logger.info("负载均衡索引为：{}", index);
                return index;
            }
        }*/
    }

    /**
     * 负载
     *
     * @param count
     * @return
     */
    private int loadBalance2(int count) {

        for (; ; ) {
            int current = atomicInteger.get();

            int next = (current + 1) % count;

            if (atomicInteger.compareAndSet(current, next)) {
                return current;
            }
        }


    }

}

